/* 
 * File:   SimplexDual.h
 * Author: bastian
 *
 * Created on 31 de mayo de 2011, 21:48
 */

#ifndef FRACCIONES_H
#include "Fracciones.h"
#define FRACCIONES_H
#endif

#ifndef MATRICES_H
#include "Matrices.h"
#define MATRICES_H
#endif

#ifndef TABLASIMPLEX_H
#include "TablaSimplex.h"
#define TABLASIMPLEX_H
#endif

#ifndef TPIVOTE_H
#include "TPivote.h"
#define TPIVOTE_H
#endif

TPivote *Dual_AnalizaFilP(TablaSimplex *tabla);
void Dual_setFilP(TablaSimplex *tabla);
int Dual_SeleccionarFilP(TPivote *elemento);
TPivote *Dual_AnalizaColP(TablaSimplex *tabla, int FilaPivote);
void Dual_setColP(TablaSimplex *tabla);
int Dual_SeleccionarColP(TPivote *elemento);


//------------------------------------------------------------------------------

TPivote *Dual_AnalizaFilP(TablaSimplex *tabla){

    int Filas = tabla->Filas;
    int Cant_Xb = Filas - 1;
    int Comparacion;
    
    Fraccion *Xb = tabla->Xb;
    Fraccion *Menor = &Xb[0];
    TPivote *FilP = TPivote_new(Cant_Xb);
    FilP->menor=Menor;
    
    LimpiarIndices(FilP->indices,Cant_Xb);
    FilP->indices[0]=0;
    
    for(int i = 1; i< Cant_Xb; i++){
        Comparacion = Fraccion_Menor(Menor,&Xb[i]);
        
        if(Comparacion==0){
            FilP->repeticiones++;
            FilP->indices[FilP->repeticiones]=i;
        }
        
        else if(Comparacion==2){
            LimpiarIndices(FilP->indices,Cant_Xb);
            FilP->repeticiones=0;
            FilP->indices[0]=i;
            FilP->menor=&Xb[i];
            Menor = &Xb[i];
        }
    }
    
    return FilP;
}

void Dual_setFilP(TablaSimplex *tabla){

    TPivote *Fila = Dual_AnalizaFilP(tabla);
    if(Fila){
        if(Fila->repeticiones==0)
            tabla->FilaPivoteDual = Fila->indices[0];
    
        else
            tabla->FilaPivoteDual = Primal_SeleccionarFilP(Fila);
    
        //free's
        free(Fila);
    }
   
}

int Dual_SeleccionarFilP(TPivote *elemento){
    
    int opcion;
    
    do{
        printf("\nFilas a Seleccionar:\n");
        for(int i = 0; i <= elemento->repeticiones; i++){
        printf("\n(%i) fila %i",i+1,(elemento->indices[i])+1);
        }
    
        printf("\nTu Opcion:");
        scanf("%i",&opcion);
    }while(opcion < 1 || opcion > elemento->repeticiones + 1);
    return elemento->indices[opcion-1];
}


//------------------------------------------------------------------------------

TPivote *Dual_AnalizaColP(TablaSimplex *tabla, int FilaPivote){
    
    int Cant_Columnas= tabla->Columnas-1;
    int j=1,primeravez=0;
    int Cont = 0, Repeticiones=0;
    int Comparacion;
    TPivote *ColP = TPivote_new(Cant_Columnas); 
    Matriz *mat = tabla->MatrizAsociada;
    Fraccion Menor,Aux;
    Fraccion *Columnas[Cant_Columnas];
    Fraccion *Zetas = tabla->Zj_Cj;
    
   
    LimpiarIndices(ColP->indices,Cant_Columnas);
    for(int i = 0; i < Cant_Columnas; i++){
        Columnas[i]=&mat->elementos[FilaPivote][i];
        if(primeravez == 0){
            if(Fraccion_esMenorQueCero(&Zetas[i])!=0 && Fraccion_esMenorQueCero(Columnas[i])==0){
                Aux = Fraccion_Dividir(&Zetas[i],Columnas[i]);
                Fraccion_abs(&Aux);
                ColP->indices[Repeticiones]=i;
                Menor = Aux;
                primeravez=1;
            
            }
            else j++;
        
        }
    }     
        
    
    
    for(int i = j; i< Cant_Columnas; i++){
       
        if(Fraccion_esMenorQueCero(&Zetas[i])!=0 && Fraccion_esMenorQueCero(Columnas[i])==0){
            
            Aux = Fraccion_Dividir(&Zetas[i],Columnas[i]);
            Comparacion = Fraccion_Menor(&Menor,&Aux);
            
            if(Comparacion==2){
                LimpiarIndices(ColP->indices,Cant_Columnas);
                Repeticiones = 0;
                ColP->indices[Repeticiones]=i;
                Menor = Aux;
            }
            
            else if(Comparacion == 0){
                Repeticiones ++;
                ColP->indices[Repeticiones]=i;
            }
        }
        else
            Cont++;
    }
    
    if(Cont==Cant_Columnas){
        free(ColP);
        return NULL;
    }
    
    else{
        ColP->menor=&Menor;
        ColP->repeticiones=Repeticiones;
        return ColP;
    }
        
    
}

void Dual_setColP(TablaSimplex *tabla){

    TPivote *Columna = Dual_AnalizaColP(tabla,tabla->FilaPivoteDual);
    
    if(Columna->repeticiones==0)
        tabla->ColumnaPivoteDual = Columna->indices[0];
    
    else
        tabla->ColumnaPivoteDual = Primal_SeleccionarColP(Columna);
    
    //free's
    free(Columna);

}

int Dual_SeleccionarColP(TPivote *elemento){
    
    int opcion;
    
    do{
        printf("\nColumnas a Seleccionar:\n");
        for(int i = 0; i <= elemento->repeticiones; i++){
        printf("\n(%i) columna %i",i+1,(elemento->indices[i])+1);
        }
    
        printf("\nTu Opcion:");
        scanf("%i",&opcion);
    }while(opcion < 1 || opcion > elemento->repeticiones + 1);
    return elemento->indices[opcion-1];
}

//------------------------------------------------------------------------------

Fraccion Dual_Impacto(TablaSimplex *tabla){

    int FilP = tabla->FilaPivoteDual;
    int ColP  = tabla->ColumnaPivoteDual;
    Fraccion Menor = tabla->Xb[0];
    Fraccion Mul,Div;
    Fraccion Pivote = tabla->MatrizAsociada->elementos[FilP][ColP];
    
    for(int i = 1; i < tabla->Filas-1; i++){
        if(Fraccion_Menor(&Menor,&tabla->Xb[i])==2)
            Menor = tabla->Xb[i];
    
    }
    
    Mul = Fraccion_Multiplicar(&tabla->Zj_Cj[ColP],&Menor);
    Div = Fraccion_Dividir(&Mul,&Pivote);
    Fraccion_abs(&Div);
    
    return Div;
}